package com.angel.configuration;

import java.util.Map;
import java.util.Properties;

import org.igfay.jfig.JFig;
import org.igfay.jfig.JFigException;
import org.igfay.jfig.JFigIF;
import org.igfay.jfig.JFigLocator;

import com.angel.architecture.exceptions.NonBusinessException;


/**
 * Esta clase es un wrapper de Jfig. Cuando se instancia, llama a su metodo privado refresh, el cual carga los parametros.
 * Dado que se registra como listener de cambios a properties, tambien ejecuta el refresh en el metodo configurationUpdate.
 *
 * @author Matias Baldini
 * @since 03-12-2007
 */
public class JFigAdapterConfiguration {
    public static JFigAdapterConfiguration INSTANCE;

    private JFigIF jFig;
    private String configFile = "io-config.xml";

    private JFigAdapterConfiguration() {
    	this("io-config.xml");
    }

    private JFigAdapterConfiguration(String fileName) {
        try {
            final JFigLocator _jFigLocator = new JFigLocator(fileName);
            _jFigLocator.setConfigLocation("classpath");
            jFig = JFig.initialize(_jFigLocator);
        }
        catch (JFigException _jfigException) {
            throw new NonBusinessException("Could not initialize configuration. Check for location of file [" + configFile + "]: " + _jfigException.getMessage(), _jfigException);
        }
    }

    public static JFigAdapterConfiguration getCurrentInstance(){
    	if(INSTANCE == null){
    		INSTANCE = new JFigAdapterConfiguration();
    	}
    	return INSTANCE;
    }
    
    public static JFigAdapterConfiguration createInstance(String fileName){
    	if(INSTANCE == null){
    		INSTANCE = new JFigAdapterConfiguration(fileName);
    	}
    	return INSTANCE;
    }
    

    public void reprocessConfiguration() {
        try {
            jFig.reprocessConfiguration(new JFigLocator(configFile));
        } catch (JFigException _jfigException) {
            throw new NonBusinessException("Could not refresh configuration. Check for location of config file " + _jfigException.getMessage(), _jfigException);
        }
    }

    /**
     * @return a map of maps with all the entries
     */
    @SuppressWarnings("unchecked")
	public Map<String, String> getEntries() {
        return jFig.getConfigDictionary().getDictionaryOfSectionDictionaries();
    }


    public boolean getBoolean(final String _section, final String _key) {
        return jFig.getBooleanValue(_section, _key, "false");
    }


    public Properties getSectionAsProperties(final String sectionName) {
        return jFig.getSectionAsProperties(sectionName);
    }


    public float getFloat(final String _section, final String _key) {
        try {
            return jFig.getFloatValue(_section, _key, "0.0");
        }
        catch (JFigException _fFigException) {
            handleException(_fFigException, _section, _key);
        }
        return 0;
    }


    public int getInt(final String _section, final String _key) {
        try {
            return jFig.getIntegerValue(_section, _key);
        }
        catch (JFigException _fFigException) {
            handleException(_fFigException, _section, _key);
        }
        return 0;
    }


    public String getString(final String _section, final String _key) {
        try {
            return jFig.getValue(_section, _key);
        }
        catch (JFigException _fFigException) {
            handleException(_fFigException, _section, _key);
        }
        return null;
    }


    @SuppressWarnings("unchecked")
	public Map<String, String> getStartingWith(final String _section, final String _key) {
        return jFig.getEntriesStartingWith(_section, _key);
    }


    public String[] getArray(final String _section, final String _key) {
        try {
            return jFig.getArrayValue(_section, _key);
        }
        catch (JFigException _fFigException) {
            handleException(_fFigException, _section, _key);
        }
        return null;
    }


    private void handleException(final JFigException _jFigException, final String _section, final String _key) {
        final StringBuffer _buffer = new StringBuffer(80);

        _buffer.append("Could not find configuration parameter for section [").
                append(_section).
                append("] with key [").
                append(_key).
                append("]: ").
                append(_jFigException.getMessage());

        throw new NonBusinessException(_buffer.toString(), _jFigException);
    }

}
